package com.ebanca.drawme;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.content.Context;
import android.content.res.XmlResourceParser;

import com.ebanca.drawme.model.Point;
import com.ebanca.drawme.util.Util;

/**
 * Class that holds loaded data from xml configuration file.
 */

public class XmlHandler implements Cloneable {

	private static final String ns = null;
	private static XmlHandler instance;
	private List<XmlConfiguration> xmlConfigurationList;
	private Context context;

	private XmlHandler() {
		//private constructor!
	}
	
	public static XmlHandler getInstance() {
		if (instance == null) {
			instance = new XmlHandler();
		}
		return instance;
	}
	
	/**
	 * Returns the the application xml configuration info object.
	 * If it wasn't loaded previously into memory, then it is loaded
	 * and returned. 
	 * 
	 * @param context the context from which the configuration file is loaded 
	 * @return application xml configuration info object
	 */
	public List<XmlConfiguration> getXmlConfiguration(Context context) {
		// if the application xml configuration info object 
		// wasn't previously loaded into memory
		if (xmlConfigurationList == null) {
			this.context = context;
			xmlConfigurationList = initializeConfigurables(context);
		}
		return xmlConfigurationList;
	}

	/**
	 * @return application xml configuration info object 
	 * 		   if it was previously loaded into memory 
	 * 		   and null, otherwise.
	 */
	public List<XmlConfiguration> getXmlConfiguration() {		
		return xmlConfigurationList;
	}
	
	private List<XmlConfiguration> initializeConfigurables(Context context) {
		List<XmlConfiguration> xmlConfigurationList = new ArrayList<XmlConfiguration>();
		
		try {
			XmlResourceParser parser = context.getResources().getXml(R.xml.config);
			while (parser.next() != XmlPullParser.END_DOCUMENT) {
				if (parser.getEventType() == XmlPullParser.START_TAG) {
					if (parser.getName().equalsIgnoreCase("draw")) {
						xmlConfigurationList.add(readDrawItem(parser));
					} 
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return xmlConfigurationList;
	}
	
	private XmlConfiguration readDrawItem(XmlPullParser parser) throws XmlPullParserException, IOException {
	    XmlConfiguration xmlConfiguration = new XmlConfiguration();
	    int i = 0;
	    while (parser.next() != XmlPullParser.END_TAG) {
	        if (parser.getEventType() != XmlPullParser.START_TAG) {
	            continue;
	        }
	        i++;
	        String name = parser.getName();
	        if (name.equalsIgnoreCase("image")) {
				xmlConfiguration.setImage(parser.getAttributeValue(ns, name));
			} 
			else if (name.equalsIgnoreCase("levelLabels")) {
				xmlConfiguration.setId(i);
			} 
			else if (name.equalsIgnoreCase("description")) {
				xmlConfiguration.setDescription(parser.getAttributeValue(ns, name));
			} 
			else if (name.equalsIgnoreCase("deviceTypes")) {
				xmlConfiguration.setDeviceCoords(getPointList(parser));
			} 
	    }
	    return xmlConfiguration;
	}
	
	private int[] getIntArray(XmlPullParser parser) {
		int[] intArray = new int[parser.getAttributeCount()];
		for (int i = 0; i < parser.getAttributeCount(); i++) {
			intArray[i] = Integer.parseInt(parser.getAttributeValue(i));
		}
		return intArray;
	}

	private int[] getDimensionIntArray(XmlPullParser parser) {
		int[] intArray = new int[parser.getAttributeCount()];
		for (int i = 0; i < parser.getAttributeCount(); i++) {
			intArray[i] = Util.getDimension(Integer.parseInt(parser
					.getAttributeValue(i)));
		}
		return intArray;
	}

	private List<Point> getPointList(XmlPullParser parser) {
		List<Point> result = new ArrayList<Point>();
		for (int i = 0; i < parser.getAttributeCount(); i++) {
			String[] split = parser.getAttributeValue(i).split(",");
			result.add(new Point(split[0],  split[1]));
		}
		return result;
	}

	private boolean[] getBoolArray(XmlPullParser parser) {
		boolean[] boolArray = new boolean[parser.getAttributeCount()];
		for (int i = 0; i < parser.getAttributeCount(); i++) {
			boolArray[i] = parser.getAttributeValue(i).equalsIgnoreCase("true");
		}
		return boolArray;
	}
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}
}
